/**
 *params
 {
    res: file, // 必选 资源
    justConversion: true, // 可选 声明了此字段说明只进行格式转换 只需再传入 res requestType responseType callback即可
    width: 500, // 可选(justConversion存在可不选) (默认图片自身宽度,建议自定义) 压缩后图片宽度
    height: 500,//可选 (默认 自定义图片宽度/原生图片宽度*原生图片高度) 压缩后图片高度
    quality: 0.2, // 可选 (默认0.3) 压缩层级质量（0<quality<1）越大压缩越快 图片质量跨度相对低 越小则相反
    size: 200, // 必选(justConversion存在可不选) 压缩后图片大小 单位k
    requestType: 'file', // 必选 传入文件类别 base64 | file | blob
    responseType: 'base64', // 必选 返回文件类别 base64 | file | blob
    imgType: 'image/jpeg', // 可选 (默认原生文件类型) 返回文件对象的文件类型
    fileName: 'ysl', // 如果responseType的类型为file和非justConversion 此选项可选 返回文件对象的文件名
    callback: (result) => {
      if (result === null) {
        alert('图片处理异常')
        return
      }
      console.log(result)
    } // 回调函数 返回处理后文件 如果为null 表示文件处理不了(原因 少了参数 参数不合法 ))
  }
 */
var CompressImage = function(b) {
  this.params = b;
  this.setImageType();
  if (this.params.justConversion) {
    this.responseData();
    return
  }
  this.quality = 1;
  this.minMultiple = 1;
  this.depPreprocessingFile = null;
  var a = this;
  if (!this.params.quality) {
    this.params.quality = 0.3
  }
  switch (this.params.requestType) {
    case "base64":
      if (this.calculatedSize(this.params.res) <= this.params.size * 1024) {
        return this.responseData(this.params.res)
      }
      this.depPreprocessingFile = this.params.res;
      this.checkAndHandleUpload();
      break;
    case "file":
    case "blob":
      if (this.params.res.size < this.params.size * 1024) {
        return this.responseData(this.params.res)
      }
      this.fileToBase64(this.params.res, function(c) {
        a.depPreprocessingFile = c;
        a.checkAndHandleUpload()
      });
      break
  }
};
CompressImage.prototype.setImageType = function() {
  if (this.params.imgType) {
    switch (this.params.requestType) {
      case "base64":
        var a = this.params.res.split(",");
        var b = a[0].match(/:(.*?);/)[1];
        this.params.res = this.params.res.replace(b, this.params.imgType);
        break;
      case "file":
        if (!this.params.fileName) {
          this.params.fileName = this.params.res.name.slice(0, /\.{1}[a-z]{1,}$/.exec(this.params.res.name).index)
        }
        case "blob":
          this.params.res.type = this.params.imgType;
          break
    }
  }
};
CompressImage.prototype.responseData = function(f) {
  var e = this;
  var b = this.params.requestType;
  var c = this.params.responseType;
  if (this.minMultiple > 1) {
    b = "base64"
  }
  if (b === c) {
    this.params.callback(f || this.params.res);
    return
  }
  var d = b + "To" + c.charAt(0).toUpperCase() + c.slice(1);
  var a = {
    "base64ToFile": this.base64ToFile.bind(this),
    "base64ToBlob": this.base64ToBlob.bind(this),
    "fileToBase64": this.fileToBase64.bind(this),
    "fileToBlob": this.fileToBlob.bind(this),
    "blobToBase64": this.blobToBase64.bind(this),
    "blobToFile": this.blobToFile.bind(this)
  };
  a[d](f || this.params.res, function(g) {
    e.params.callback(g)
  })
};
CompressImage.prototype.calculatedSize = function(c) {
  var a = "base64";
  var b = c.substring(c.indexOf(a) + a.length);
  var d = b.indexOf("=");
  b = d !== -1 ? b.substring(0, d) : b;
  var e = b.length;
  return e - (e / 8) * 2
};
CompressImage.prototype.checkAndHandleUpload = function() {
  var b = this;
  try {
    var a = new Image();
    a.src = this.depPreprocessingFile;
    a.onload = function() {
      var g = document.createElement("canvas");
      var f = g.getContext("2d");
      var h = b.params.width || this.width;
      g.width = h;
      g.height = b.params.height || this.height * (h / this.width);
      f.clearRect(0, 0, g.width, g.height);
      f.drawImage(a, 0, 0, g.width, g.height);
      var e = g.toDataURL("image/jpeg", b.quality);
      var d = b.calculatedSize(e);
      b.minMultiple += 1;
      if (d < b.params.size * 1024) {
        b.responseData(e)
      } else {
        if (b.quality > b.params.quality) {
          if (b.quality === 1) {
            b.depPreprocessingFile = e
          }
          b.quality -= b.params.quality
        } else {
          b.responseData(e);
          return
        }
        if (b.minMultiple > 25) {
          b.responseData(e);
          return
        }
        b.checkAndHandleUpload()
      }
    }
  } catch (c) {
    this.params.callback(null)
  }
};
CompressImage.prototype.base64ToFile = function(f, h) {
  var a = f.split(",");
  var d = a[0].match(/:(.*?);/)[1];
  var e = d.split("/")[1];
  var b = atob(a[1]);
  var g = b.length;
  var c = new Uint8Array(g);
  while (g--) {
    c[g] = b.charCodeAt(g)
  }
  h(new File([c], (this.params.fileName || "file") + "." + e, {
    type: d
  }))
};
CompressImage.prototype.base64ToBlob = function(f, h) {
  var g = f.split(",");
  var a = "";
  var e = "";
  if (g.length > 1) {
    e = g[1];
    a = g[0].substring(g[0].indexOf(":") + 1, g[0].indexOf(";"))
  }
  var j = atob(e);
  var c = new ArrayBuffer(j.length);
  var b = new Uint8Array(c);
  for (var d = 0; d < j.length; d++) {
    b[d] = j.charCodeAt(d)
  }
  h(new Blob([c], {
    type: a
  }))
};
CompressImage.prototype.fileToBase64 = function(b, c) {
  var a = new FileReader();
  a.readAsDataURL(b);
  a.onload = function(d) {
    c(this.result)
  }
};
CompressImage.prototype.fileToBlob = function(a, c) {
  var b = this;
  this.fileToBase64(a, function(d) {
    b.base64ToBlob(d, function(e) {
      c(e)
    })
  })
};
CompressImage.prototype.blobToBase64 = function(a, b) {
  this.fileToBase64(a, b)
};
CompressImage.prototype.blobToFile = function(a, b) {
  this.fileToBlob(a, function(c) {
    b(c)
  })
};
module.exports = CompressImage;